#include "pub.h"

void OutputDepth( int depth )
{
	int	i ;
	
	for( i = 1 ; i < depth ; i++ )
		printf( "\t" );
	
	return ;
}

void OutputDomNode( struct DomNode *node , int depth )
{
	char			*node_name ;
	enum DomNodeType	node_type ;
	char			*s = NULL ;
	long			l ;
	double			d ;
	unsigned char		b ;
	enum DomNodeExist	is_exist ;
	struct DomNode		*prop_node = NULL ;
	
	OutputDepth( depth );
	
	printf( "node_name[%s]" , GetDomNodeName(node) );
	
	node_type = GetDomNodeType( node ) ;
	switch( node_type )
	{
		case DOMNODE_TYPE_BRANCH :
			printf( " BARNCH" );
			break;
		case DOMNODE_TYPE_ARRAY :
			printf( " ARRAY" );
			break;
		case DOMNODE_TYPE_STRING :
			s = GetDomNodeData_string( node , & is_exist ) ;
			if( is_exist == DOMNODE_NODE_DATA_EXIST )
			{
				if( IsXmlCdataDomNode(node) == 0 )
					printf( " node_data:string[%s]" , s );
				else
					printf( " node_data:cdata[%s]" , s );
			}
			break;
		case DOMNODE_TYPE_LONG :
			l = GetDomNodeData_long( node , & is_exist ) ;
			if( is_exist == DOMNODE_NODE_DATA_EXIST )
				printf( " node_data:long[%ld]" , l );
			break;
		case DOMNODE_TYPE_DOUBLE :
			d = GetDomNodeData_double( node , & is_exist ) ;
			if( is_exist == DOMNODE_NODE_DATA_EXIST )
				printf( " node_data:double[%lf]" , d );
			break;
		case DOMNODE_TYPE_BOOL :
			b = GetDomNodeData_bool( node , & is_exist ) ;
			if( is_exist == DOMNODE_NODE_DATA_EXIST )
				printf( " node_data:bool[%d]" , b );
			break;
		default :
			printf( " UNKNOW-NODE-DATA-TYPE" );
			break;
	}
	
	prop_node = GetFirstXmlPropertyDomNode( node ) ;
	while( prop_node )
	{
		node_name = GetDomNodeName( prop_node ) ;
		node_type = GetDomNodeType( prop_node ) ;
		switch( node_type )
		{
			case DOMNODE_TYPE_STRING :
				s = GetDomNodeData_string( prop_node , & is_exist ) ;
				if( is_exist == DOMNODE_NODE_DATA_EXIST )
					printf( " prop:string[%s][%s]" , node_name , s );
				break;
			case DOMNODE_TYPE_LONG :
				l = GetDomNodeData_long( prop_node , & is_exist ) ;
				if( is_exist == DOMNODE_NODE_DATA_EXIST )
					printf( " prop:long[%s][%ld]" , node_name , l );
				break;
			case DOMNODE_TYPE_DOUBLE :
				d = GetDomNodeData_double( prop_node , & is_exist ) ;
				if( is_exist == DOMNODE_NODE_DATA_EXIST )
					printf( " prop:double[%s][%lf]" , node_name , d );
				break;
			case DOMNODE_TYPE_BOOL :
				b = GetDomNodeData_bool( prop_node , & is_exist ) ;
				if( is_exist == DOMNODE_NODE_DATA_EXIST )
					printf( " prop:bool[%s][%d]" , node_name , b );
				break;
			default :
				printf( " UNKNOW-NODE-PROPERTY" );
				break;
		}
		
		prop_node = GetNextXmlPropertyDomNode( prop_node ) ;
	}
	
	printf( "\n" );
	
	return;
}

void _OutputDomNodes( struct DomNode *root_node , int depth )
{
	struct DomNode	*node = GetFirstDomNode( root_node ) ;
	
	while( node )
	{
		OutputDomNode( node , depth+1 );
		
		if( GetChildrenDomNodes(node) )
			_OutputDomNodes( GetChildrenDomNodes(node) , depth+1 );
		
		node = GetNextDomNode(node) ;
	}
	
	return;
}

void OutputDomNodes( struct DomNode *root_node )
{
	if( GetDomNodeXmlDeclarationPtr(root_node) )
		_OutputDomNodes( GetDomNodeXmlDeclarationPtr(root_node) , 0 );
		
	_OutputDomNodes( root_node , 0 );
	
	return;
}

static long _GetFileSize(char *filename)
{
	struct stat stat_buf;
	int ret;

	ret=stat(filename,&stat_buf);
	
	if( ret == -1 )
		return -1;
	
	return stat_buf.st_size;
}

static int ReadEntireFile( char *filename , char *mode , char *buf , long *bufsize )
{
	FILE	*fp = NULL ;
	long	filesize ;
	long	lret ;
	
	if( filename == NULL )
		return -1;
	if( strcmp( filename , "" ) == 0 )
		return -1;
	
	filesize = _GetFileSize( filename ) ;
	if( filesize  < 0 )
		return -2;
	
	fp = fopen( filename , mode ) ;
	if( fp == NULL )
		return -3;
	
	if( filesize <= (*bufsize) )
	{
		lret = (long)fread( buf , sizeof(char) , filesize , fp ) ;
		if( lret < filesize )
		{
			fclose( fp );
			return -4;
		}
		
		(*bufsize) = filesize ;
		
		fclose( fp );
		
		return 0;
	}
	else
	{
		lret = (long)fread( buf , sizeof(char) , (*bufsize) , fp ) ;
		if( lret < (*bufsize) )
		{
			fclose( fp );
			return -4;
		}
		
		fclose( fp );
		
		return 1;
	}
}

int ReadEntireFileSafely( char *filename , char *mode , char **pbuf , long *pbufsize )
{
	long	filesize ;
	
	int	nret ;
	
	filesize = _GetFileSize( filename );
	
	(*pbuf) = (char*)malloc( filesize + 1 ) ;
	if( (*pbuf) == NULL )
		return -1;
	memset( (*pbuf) , 0x00 , filesize + 1 );
	
	nret = ReadEntireFile( filename , mode , (*pbuf) , & filesize ) ;
	if( nret )
	{
		free( (*pbuf) );
		(*pbuf) = NULL ;
		return nret;
	}
	else
	{
		if( pbufsize )
			(*pbufsize) = filesize ;
		return 0;
	}
}

